﻿/*******************************************************************************
 * 作者: hao.wang
 * 时间: 2013-10-29 17:14:54
 * 描述说明:
 *     
 * 更改历史:
 *     
*******************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.CompilerServices;
using ChinaScope.CSF.Common;

namespace ChinaScope.CSF.LogCenter
{
    internal class MemoryQueue
    {
        private static Queue<AbstractLogInfo> memoryInfoQueue = new Queue<AbstractLogInfo>();
        private static object memoryInfoQueueLocker = new object();
        private static bool enabled = true;
        private static List<Thread> workThreadList = new List<Thread>();

        public static void BatchEnqueue(List<AbstractLogInfo> infoList)
        {
            lock (memoryInfoQueueLocker)
            {
                foreach (var info in infoList)
                {
                    if (memoryInfoQueue.Count >= ConfigProvider.MemoryQueueMaxCount)
                        memoryInfoQueue.Dequeue();
                    memoryInfoQueue.Enqueue(info);
                }
            }
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void Start()
        {
            ConfigProvider.Init();

            memoryInfoQueue = new Queue<AbstractLogInfo>();
            for (int i = 0; i <= ConfigProvider.WorkThreadCount; i++)
            {
                Thread t = new Thread(WorkMethod);
                t.IsBackground = true;
                t.Name = "LogCenter.Memqueue " + i.ToString();
                workThreadList.Add(t);
            }
            foreach (var t in workThreadList)
            {
                t.Start();
            }
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static void End()
        {
            enabled = false;
            foreach (var t in workThreadList)
            {
                t.Join();
            }
        }
        public static void WorkMethod()
        {
            while (enabled)
            {
                Thread.Sleep(ConfigProvider.WorkThreadSleepInterval);
                SaveBatch();
            }
        }
        public static void SaveBatch()
        {
            List<AbstractLogInfo> list = new List<AbstractLogInfo>();
            for (int i = 0; i < ConfigProvider.SubmitToServerBatchSize; i++)
            {
                var info = Dequeue();
                if (info != null)
                {
                    list.Add(info);
                }
            }
            if (list.Count > 0)
            {
                try
                {
                    new MongoDBAccess().SaveData(list);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
                }
            }
        }
        public static AbstractLogInfo Dequeue()
        {
            lock (memoryInfoQueueLocker)
            {
                if (memoryInfoQueue.Count > 0)
                {
                    return memoryInfoQueue.Dequeue();
                }
                return null;
            }
        }
    }
}
